package com.apesay.plugins;

import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

/**
 * ClassName:UserVisitor
 * Reason:	 
 * Date:     2017/11/10 12:00
 *
 * @author sid
 */
public class UserMethodVisitor extends MethodVisitor {

    public UserMethodVisitor(int i, MethodVisitor methodVisitor) {
        super(i, methodVisitor);
    }

    @Override
    public void visitCode() {
        super.visitCode();

        mv.visitFieldInsn(Opcodes.GETSTATIC,"java/lang/System","out","Ljava/io/PrintStream;");
        // pushes the "Hello World!" String constant  
        mv.visitLdcInsn("asm method before!");
        // invokes the 'println' method (defined in the PrintStream class)  
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,"java/io/PrintStream","println","(Ljava/lang/String;)V");
        
//        this.visitMethodInsn(Opcodes.INVOKESTATIC, "com/apesay/plugins/UserAop", "before", "()V",false);
//        System.out.println("UserMethodVisitor.visitCode");
//
//        mv.visitFieldInsn(Opcodes.GETSTATIC, "com/apesay/test/User", "timer", "J");
//        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "currentTimeMillis", "()J");
//        mv.visitInsn(Opcodes.LSUB);
//        mv.visitFieldInsn(Opcodes.PUTSTATIC, "com/apesay/test/User", "timer", "J");
    }

    @Override
    public void visitInsn(int opcode) {
        //此方法可以获取方法中每一条指令的操作类型，被访问多次  
        //如应在方法结尾处添加新指令，则应判断：  
        if(opcode>=Opcodes.IRETURN && opcode <= Opcodes.RETURN)
        {
//            System.out.println("UserMethodVisitor.visitInsn");
//
//            mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
//            mv.visitFieldInsn(Opcodes.GETSTATIC, "com/apesay/test/User", "timer", "J");
//            mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "currentTimeMillis", "()J");
//            mv.visitInsn(Opcodes.LADD);
//            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(J)V");

            mv.visitFieldInsn(Opcodes.GETSTATIC,"java/lang/System","out","Ljava/io/PrintStream;");
            // pushes the "Hello World!" String constant  
            mv.visitLdcInsn("asm method after!");
            // invokes the 'println' method (defined in the PrintStream class)  
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,"java/io/PrintStream","println","(Ljava/lang/String;)V");
        }
        super.visitInsn(opcode);
//        System.out.println("UserMethodVisitor.visitInsn");
    }

    @Override
    public void visitEnd() {
//        this.visitMethodInsn(Opcodes.INVOKESTATIC, "com/apesay/plugins/UserAop", "after", "()V",false);
//        System.out.println("UserMethodVisitor.visitEnd");
//        this.visitFieldInsn(Opcodes.GETSTATIC,"java/lang/System","out","Ljava/io/PrintStream;");
//        // pushes the "Hello World!" String constant  
//        this.visitLdcInsn("this is a modify method!");
//        // invokes the 'println' method (defined in the PrintStream class)  
//        this.visitMethodInsn(Opcodes.INVOKEVIRTUAL,"java/io/PrintStream","println","(Ljava/lang/String;)V");
        super.visitEnd();
    }
}
